package org.loofer.ext.component.drawable;

import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;

public class ScaleDrawable extends DrawableDecorator {
    private static final float PIVOT_DEFAULT_VALUE = 0.0f;
    private Matrix mDrawMatrix;
    private float mPivotXRate;
    private float mPivotYRate;
    private ScaleState mScaleState;
    private ScaleType mScaleType;
    private Rect mTmpRect;

    static class ScaleState extends DrawableDecoratorState {
        ScaleState(ScaleState orig, ScaleDrawable owner, Resources res) {
            super(orig, owner, res);
        }

        public Drawable newDrawable() {
            return new ScaleDrawable(this, null);
        }

        public Drawable newDrawable(Resources res) {
            return new ScaleDrawable(this, res);
        }
    }

    public enum ScaleType {
        CROP_CENTER(0),
        CROP_START(1),
        CROP_END(2),
        FIT_CENTER(3),
        FIT_START(4),
        FIT_END(5),
        MATCH_WIDTH_TOP(6),
        MATCH_WIDTH_BOTTOM(7),
        MATCH_WIDTH_CENTER(8),
        CENTER(9),
        CROP_BY_PIVOT(10);
        
        final int nativeInt;

        private ScaleType(int ni) {
            this.nativeInt = ni;
        }
    }

    public ScaleDrawable(Drawable drawable) {
        this(drawable, null);
    }

    public ScaleDrawable(Drawable drawable, ScaleType scaleType) {
        this.mPivotXRate = 0.0f;
        this.mPivotYRate = 0.0f;
        this.mTmpRect = new Rect();
        this.mScaleState = new ScaleState(null, this, null);
        this.mScaleState.setDrawable(drawable);
        setConstantState(this.mScaleState);
        setScaleType(scaleType);
    }

    public void setScaleType(ScaleType scaleType) {
        if (this.mScaleType != scaleType) {
            this.mScaleType = scaleType;
            updateDrawMatrix();
        }
    }

    public void setPivot(float x, float y) {
        if (this.mPivotXRate != x || this.mPivotYRate != y) {
            this.mPivotXRate = x;
            this.mPivotYRate = y;
            updateDrawMatrix();
        }
    }

    protected void onBoundsChange(Rect bounds) {
        int width = getIntrinsicWidth();
        int height = getIntrinsicHeight();
        Rect tmpBounds = bounds;
        if (width > 0 && height > 0) {
            tmpBounds = this.mTmpRect;
            tmpBounds.set(0, 0, width, height);
        }
        super.onBoundsChange(tmpBounds);
        updateDrawMatrix();
    }

    public void draw(Canvas canvas) {
        Matrix drawMatrix = this.mDrawMatrix;
        if (drawMatrix == null || drawMatrix.isIdentity()) {
            super.draw(canvas);
            return;
        }
        int saveCount = canvas.getSaveCount();
        canvas.save();
        canvas.concat(drawMatrix);
        super.draw(canvas);
        canvas.restoreToCount(saveCount);
    }

    public int getMinimumWidth() {
        return 0;
    }

    public int getMinimumHeight() {
        return 0;
    }

    public ConstantState getConstantState() {
        if (!this.mScaleState.canConstantState()) {
            return null;
        }
        this.mScaleState.mChangingConfigurations = getChangingConfigurations();
        return this.mScaleState;
    }

    private void updateDrawMatrix() {
        ScaleType scaleType = this.mScaleType;
        if (scaleType != null) {
            float scale;
            if (this.mDrawMatrix == null) {
                this.mDrawMatrix = new Matrix();
            }
            int srcWidth = getIntrinsicWidth();
            int srcHeight = getIntrinsicHeight();
            int dstWidth = getBounds().width();
            int dstHeight = getBounds().height();
            float dx;
            float dy;
            switch (scaleType) {
                case CROP_CENTER:
                    dx = 0.0f;
                    dy = 0.0f;
                    if (srcWidth * dstHeight > dstWidth * srcHeight) {
                        scale = ((float) dstHeight) / ((float) srcHeight);
                        dx = (((float) dstWidth) - (((float) srcWidth) * scale)) * 0.5f;
                    } else {
                        scale = ((float) dstWidth) / ((float) srcWidth);
                        dy = (((float) dstHeight) - (((float) srcHeight) * scale)) * 0.5f;
                    }
                    this.mDrawMatrix.setScale(scale, scale);
                    this.mDrawMatrix.postTranslate((float) ((int) (0.5f + dx)), (float) ((int) (0.5f + dy)));
                    return;
                case CROP_START:
                    dx = 0.0f;
                    dy = 0.0f;
                    if (srcWidth * dstHeight > dstWidth * srcHeight) {
                        scale = ((float) dstHeight) / ((float) srcHeight);
                        dx = 0.0f;
                    } else {
                        scale = ((float) dstWidth) / ((float) srcWidth);
                        dy = 0.0f;
                    }
                    this.mDrawMatrix.setScale(scale, scale);
                    this.mDrawMatrix.postTranslate((float) ((int) (0.5f + dx)), (float) ((int) (0.5f + dy)));
                    return;
                case CROP_END:
                    dx = 0.0f;
                    dy = 0.0f;
                    if (srcWidth * dstHeight > dstWidth * srcHeight) {
                        scale = ((float) dstHeight) / ((float) srcHeight);
                        dx = (((float) dstWidth) - (((float) srcWidth) * scale)) * 1.0f;
                    } else {
                        scale = ((float) dstWidth) / ((float) srcWidth);
                        dy = (((float) dstHeight) - (((float) srcHeight) * scale)) * 1.0f;
                    }
                    this.mDrawMatrix.setScale(scale, scale);
                    this.mDrawMatrix.postTranslate((float) ((int) (0.5f + dx)), (float) ((int) (0.5f + dy)));
                    return;
                case FIT_CENTER:
                    dx = 0.0f;
                    dy = 0.0f;
                    if (srcWidth * dstHeight > dstWidth * srcHeight) {
                        scale = ((float) dstWidth) / ((float) srcWidth);
                        dy = (((float) dstHeight) - (((float) srcHeight) * scale)) * 0.5f;
                    } else {
                        scale = ((float) dstHeight) / ((float) srcHeight);
                        dx = (((float) dstWidth) - (((float) srcWidth) * scale)) * 0.5f;
                    }
                    this.mDrawMatrix.setScale(scale, scale);
                    this.mDrawMatrix.postTranslate((float) ((int) (0.5f + dx)), (float) ((int) (0.5f + dy)));
                    return;
                case FIT_START:
                    dx = 0.0f;
                    dy = 0.0f;
                    if (srcWidth * dstHeight > dstWidth * srcHeight) {
                        scale = ((float) dstWidth) / ((float) srcWidth);
                        dy = 0.0f;
                    } else {
                        scale = ((float) dstHeight) / ((float) srcHeight);
                        dx = 0.0f;
                    }
                    this.mDrawMatrix.setScale(scale, scale);
                    this.mDrawMatrix.postTranslate((float) ((int) (0.5f + dx)), (float) ((int) (0.5f + dy)));
                    return;
                case FIT_END:
                    dx = 0.0f;
                    dy = 0.0f;
                    if (srcWidth * dstHeight > dstWidth * srcHeight) {
                        scale = ((float) dstWidth) / ((float) srcWidth);
                        dy = (((float) dstHeight) - (((float) srcHeight) * scale)) * 1.0f;
                    } else {
                        scale = ((float) dstHeight) / ((float) srcHeight);
                        dx = (((float) dstWidth) - (((float) srcWidth) * scale)) * 1.0f;
                    }
                    this.mDrawMatrix.setScale(scale, scale);
                    this.mDrawMatrix.postTranslate((float) ((int) (0.5f + dx)), (float) ((int) (0.5f + dy)));
                    break;
                case MATCH_WIDTH_TOP:
                    break;
                case MATCH_WIDTH_BOTTOM:
                    scale = ((float) dstWidth) / ((float) srcWidth);
                    dy = (((float) dstHeight) - (((float) srcHeight) * scale)) * 1.0f;
                    this.mDrawMatrix.setScale(scale, scale);
                    this.mDrawMatrix.postTranslate((float) ((int) (0.5f + 0.0f)), (float) ((int) (0.5f + dy)));
                    return;
                case MATCH_WIDTH_CENTER:
                    scale = ((float) dstWidth) / ((float) srcWidth);
                    dy = (((float) dstHeight) - (((float) srcHeight) * scale)) * 0.5f;
                    this.mDrawMatrix.setScale(scale, scale);
                    this.mDrawMatrix.postTranslate((float) ((int) (0.5f + 0.0f)), (float) ((int) (0.5f + dy)));
                    return;
                case CENTER:
                    dx = ((float) (dstWidth - srcWidth)) * 0.5f;
                    this.mDrawMatrix.postTranslate((float) ((int) (0.5f + dx)), (float) ((int) (0.5f + (((float) (dstHeight - srcHeight)) * 0.5f))));
                    return;
                case CROP_BY_PIVOT:
                    if (srcWidth * dstHeight > dstWidth * srcHeight) {
                        scale = ((float) dstHeight) / ((float) srcHeight);
                    } else {
                        scale = ((float) dstWidth) / ((float) srcWidth);
                    }
                    float halfWidth = ((float) dstWidth) * 0.5f;
                    float halfHeight = ((float) dstHeight) * 0.5f;
                    float startX = 0.0f;
                    float startY = 0.0f;
                    srcWidth = (int) (((float) srcWidth) * scale);
                    srcHeight = (int) (((float) srcHeight) * scale);
                    float pivotX = this.mPivotXRate * ((float) srcWidth);
                    float pivotY = this.mPivotYRate * ((float) srcHeight);
                    if (srcWidth > dstWidth && pivotX > halfWidth) {
                        startX = Math.min((float) (srcWidth - dstWidth), pivotX - halfWidth);
                    }
                    if (srcHeight > dstHeight && pivotY > halfHeight) {
                        startY = Math.min((float) (srcHeight - dstHeight), pivotY - halfHeight);
                    }
                    this.mDrawMatrix.setScale(scale, scale);
                    this.mDrawMatrix.postTranslate((float) (((int) (0.5f + startX)) * -1), (float) (((int) (0.5f + startY)) * -1));
                    return;
                default:
                    return;
            }
            scale = ((float) dstWidth) / ((float) srcWidth);
            this.mDrawMatrix.setScale(scale, scale);
            this.mDrawMatrix.postTranslate((float) ((int) (0.5f + 0.0f)), (float) ((int) (0.5f + 0.0f)));
        } else if (this.mDrawMatrix != null) {
            this.mDrawMatrix.reset();
        }
    }

    private ScaleDrawable(ScaleState state, Resources res) {
        this.mPivotXRate = 0.0f;
        this.mPivotYRate = 0.0f;
        this.mTmpRect = new Rect();
        this.mScaleState = new ScaleState(state, this, res);
        setConstantState(this.mScaleState);
    }
}
